package com.lzy.system.organization.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lzy.cacheAnno.RedisCache;
import com.lzy.cacheAnno.RedisCacheDel;
import com.lzy.conf.I18nServiceImpl;
import com.lzy.exception.BusException;
import com.lzy.system.organization.config.PlatformUserConfig;
import com.lzy.system.organization.dto.SysUserDTO;
import com.lzy.system.organization.entity.SysUser;
import com.lzy.system.organization.entity.security.entity.SecurityUser;
import com.lzy.system.organization.mapper.SysUserMapper;
import com.lzy.system.organization.service.ISysUserService;
import com.lzy.system.organization.util.UserCommon;
import com.lzy.system.organization.vo.SysUserVo;
import com.lzy.utils.BeanMapHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author lcc
 * @since 2022-08-13
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {
    private SysUserMapper userMapper;
    private I18nServiceImpl i18nService;
    private RedisTemplate redisTemplate;
    private UserCommon userCommon;

    private PlatformUserConfig platformUserConfig;

    @Autowired
    public SysUserServiceImpl(SysUserMapper userMapper, I18nServiceImpl i18nService, RedisTemplate redisTemplate, UserCommon userCommon, PlatformUserConfig platformUserConfig) {
        this.userMapper = userMapper;
        this.i18nService = i18nService;
        this.redisTemplate = redisTemplate;
        this.userCommon = userCommon;
        this.platformUserConfig = platformUserConfig;
    }

    @Override
    public void exitLogin(SecurityUser securityUser) throws BusException {
        boolean delete = redisTemplate.delete("token-"+securityUser.getToken_uuid());
        if (!delete) {
            throw new BusException(i18nService.getMessage("exitLogin.error"));
        }
    }

    @Override
    public SysUserVo getUserByUserId(String userId) throws BusException {
        return userMapper.findByUsername(userId);
    }

    @Override
    @RedisCache(value = {"id"}, key = "user:entity", extKey = "#id")
    public SysUserVo getUserById(Long id) throws BusException {
        return userMapper.findById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(List<SysUserDTO> sysUserDTOs) throws BusException {
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        List<SysUser> sysUsers = new ArrayList<>();
        for (SysUserDTO sysUserDTO : sysUserDTOs) {
            //检测用户是否存在
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("username", sysUserDTO.getUsername());
            queryWrapper.select("id", "username", "nickname");
            SysUser one = this.getOne(queryWrapper);
            if (one != null) {
                throw new BusException(i18nService.getMessage("system.org.user.exists"));
            }
            SysUser sysUser = (SysUser) BeanMapHelper.Bean2Bean(sysUserDTO, SysUser.class);
            sysUser.setPassword(bCryptPasswordEncoder.encode(platformUserConfig.getDef_pwd()));//编码
            sysUsers.add(sysUser);
        }
        boolean update = this.saveBatch(sysUsers);
        if (!update) {
            throw new BusException(i18nService.getMessage("system.org.user.add.fail"));
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @RedisCacheDel(value = {"users"}, key = "user:entity",isFor = true, extKey = "T(org.springframework.util.StringUtils).collectionToDelimitedString(#users.![id], ',')")
    public boolean update(List<SysUserDTO> sysUserDTOs) throws BusException {
        List<SysUser> sysUsers = new ArrayList<>();
        for (SysUserDTO sysUserDTO : sysUserDTOs) {
            SysUser sysUser = (SysUser) BeanMapHelper.Bean2Bean(sysUserDTO, SysUser.class);
            sysUsers.add(sysUser);
        }
        boolean update = this.updateBatchById(sysUsers);
        if (!update) {
            throw new BusException(i18nService.getMessage("system.org.user.update.fail"));
        }
        return update;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean del(String ids) throws BusException {
        ArrayList<Integer> ids_arr = new ArrayList<>();
        for (int i : StrUtil.splitToInt(ids, ",")) {
            ids_arr.add(i);
        }
        boolean remove = this.removeBatchByIds(ids_arr);
        if (!remove) {
            throw new BusException(i18nService.getMessage("system.org.user.del.fail"));
        }
        return remove;
    }

    @Override
    public IPage<SysUserVo> getList(String username, String nickname, int limit, int page) throws BusException {
        Page<SysUser> Ipage = new Page<>(page, limit);
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper();
        if (!StrUtil.isBlank(username)) {
            queryWrapper.like("username", username);
            queryWrapper.or();
        }
        if (!StrUtil.isBlank(nickname)) {
            queryWrapper.like("nickname", nickname);
            queryWrapper.or();
        }
        queryWrapper.orderByDesc("createdate");
        IPage res = this.page(Ipage, queryWrapper);
        return res;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updatePwd(String pwd_old, String pwd_new, String pwd_confirm) throws BusException {
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        SysUser one = this.getOne(new QueryWrapper() {{
            eq("username", userCommon.getCurrentUserId());
        }});
        if (one == null) {
            throw new BusException("用户不存在");
        }

        if (!bCryptPasswordEncoder.matches(pwd_old, one.getPassword())) {
            throw new BusException("旧密码不正确");
        }

        if (!pwd_new.equals(pwd_confirm)) {
            throw new BusException("两次输入密码不一致");
        }
        SysUser sysUser = new SysUser();
        sysUser.setPassword(bCryptPasswordEncoder.encode(pwd_new));
        boolean isUpdate = update(sysUser, new UpdateWrapper() {{
            eq("username", userCommon.getCurrentUserId());
        }});

        if (!isUpdate) {
            throw new BusException("修改密码失败");
        }
    }
}
